/*
 * @Author: haungyan
 * @Date: 2020-11-19 14:03:21
 * @LastEditors: haungyan
 * @LastEditTime: 2020-12-29 11:59:54
 * @Description: file content
 * @FilePath: \test-lint\src\vueRouter\index.js
 */
let _vue = null
export default class VueRouter {
    constructor({ mode = 'history', base = '/', routes = [] }) {
        this.mode = mode
        this.base = base
        this.routeMap = routes
        this.currentPath = base
        this.initComponents()
        this.initEvent()
        this.state = _vue.observable({ currentPath: this.initCurrentPath(mode) })
    }

    static install(vue) {
        if (_vue) {
            return false
        }
        _vue = vue
        _vue.mixin({
            beforeCreate() {
                if (this.$options.router) {
                    _vue.prototype.$router = this.$options.router
                    _vue.prototype.$routes = this.$options.router.routeMap
                }
            }
        })
    }

    // 注册router-link 和 router-view组件
    initComponents() {
        const self = this
        _vue.component('router-link', {
            props: {
                to: String
            },
            methods: {
                handler(e) {
                    e.preventDefault()
                    if (this.mode == 'history') {
                        this.handlerHistory()
                    } else {
                        this.handlerHash()
                    }
                },
                // history跳转
                handlerHistory() {
                    self.state.currentPath = this.to
                    window.history.pushState(null, null, this.to)
                    // _vue.prototype.$routes = self.routeMap.find(item => item.path === self.state.currentPath)
                },
                // hash 模式跳转
                handlerHash() {
                    self.state.currentPath = this.to
                    location.hash = this.to
                    // console.log(location.hash, this.to)
                }
            },
            render(h) {
                return <a href={this.to} onClick={(e) => {this.handler(e)}}>{this.$slots.default}</a>
            }
        })
        _vue.component('router-view', {
            render(h) {
                const component = self.routeMap.find(item => item.path === self.state.currentPath).component

                return h(component)
            }
        })
    }

    initEvent() {
        window.onpopstate = () => {
            this.state.currentPath = location.pathname
            // _vue.prototype.$routes = this.routeMap.find(item => item.path === this.state.currentPath)
        }
        window.onhashchange = () => {
            this.state.currentPath = location.hash.substr(1)
        }
    }

    // 初始化默认路径
    initCurrentPath(mode) {
        if(mode === 'history'){
            return window.location.pathname || '/'
        }

        // 默认 hash 模式(保证刷新还是当前组件)
        window.location.hash = window.location.hash ? window.location.hash : '#/'
        return window.location.hash ? window.location.hash.substr(1) : '#/'
    }
}